In [1]:
#conda install Pillow

COMPUTER VISION¶

Computer vision is a field of artificial intelligence that gives computers the ability to see, understand, and interpret the visual world The goal of computer vision is to enable computers to see the world in the same way that humans do. This is a challenging task, as the visual world is complex and constantly changing. However, recent advances in artificial intelligence and machine learning have made significant progress in the field of computer vision

First, let me define some terms...

What is an Image?

A digital image is not a continuous image, like a painting or a photograph. Instead, it is made up of a grid of pixels, and each pixel has a specific value that represents its color or brightness. It is an array of pixels arranged in columns and rows. Pixels are the elements of an image that contain information about intensity and color. Pixels are arranged in the form of a matrix. This is known as an RGB image

What is Image Processing?

Image Processing is the core part of computer vision. It plays a crucial role in many real-world examples like robotics, self-driving cars, and object detection. Image processing allows us to transform and manipulate thousands of images at a time and extract useful insights from them. It has a wide range of applications in almost every field.

Why Python?

Python is one of the widely used programming languages for this purpose. Its amazing libraries and tools help in achieving the task of image processing very efficiently.

What I will be exploring today..

  • Basic image processing using Python Numpy, Pillow and OpenCV
  • working with image data as structured arrays
  • understanding and working with color channels
  • creating/drawing graphics and shapes programmatically
In [2]:
#importing required libraries
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image
import cv2
In [3]:
#importing images using numpy
pic = plt.imread(r"C:\Users\Mumsie\images\chi.png")
pic
Out[3]:
array([[[0.64705884, 0.6509804 , 0.627451  ],
        [0.64705884, 0.65882355, 0.6392157 ],
        [0.6509804 , 0.654902  , 0.63529414],
        ...,
        [0.654902  , 0.65882355, 0.63529414],
        [0.6509804 , 0.654902  , 0.6313726 ],
        [0.65882355, 0.65882355, 0.6392157 ]],

       [[0.654902  , 0.65882355, 0.63529414],
        [0.654902  , 0.65882355, 0.63529414],
        [0.65882355, 0.6627451 , 0.6431373 ],
        ...,
        [0.654902  , 0.65882355, 0.63529414],
        [0.64705884, 0.6509804 , 0.63529414],
        [0.654902  , 0.65882355, 0.6392157 ]],

       [[0.64705884, 0.65882355, 0.6313726 ],
        [0.64705884, 0.6509804 , 0.627451  ],
        [0.65882355, 0.6627451 , 0.6392157 ],
        ...,
        [0.6509804 , 0.654902  , 0.63529414],
        [0.6392157 , 0.6431373 , 0.627451  ],
        [0.6509804 , 0.6509804 , 0.63529414]],

       ...,

       [[0.9647059 , 0.4392157 , 0.59607846],
        [0.9529412 , 0.43137255, 0.5921569 ],
        [0.9254902 , 0.43529412, 0.58431375],
        ...,
        [0.5176471 , 0.90588236, 0.9764706 ],
        [0.49019608, 0.8901961 , 0.9607843 ],
        [0.29411766, 0.7254902 , 0.8       ]],

       [[0.9764706 , 0.44705883, 0.60784316],
        [0.96862745, 0.44313726, 0.6039216 ],
        [0.9490196 , 0.45882353, 0.6039216 ],
        ...,
        [0.4862745 , 0.8901961 , 0.9647059 ],
        [0.48235294, 0.9137255 , 0.98039216],
        [0.34117648, 0.8235294 , 0.8784314 ]],

       [[0.98039216, 0.4627451 , 0.61960787],
        [0.9882353 , 0.45490196, 0.6156863 ],
        [0.9647059 , 0.4745098 , 0.61960787],
        ...,
        [0.3529412 , 0.78039217, 0.8627451 ],
        [0.43529412, 0.9019608 , 0.96862745],
        [0.38039216, 0.90588236, 0.9529412 ]]], dtype=float32)
In [4]:
plt.imshow(pic);
In [5]:
#R(0), G(1), B(2)

#filtering by Red

pic[:,:,0]
Out[5]:
array([[0.64705884, 0.64705884, 0.6509804 , ..., 0.654902  , 0.6509804 ,
        0.65882355],
       [0.654902  , 0.654902  , 0.65882355, ..., 0.654902  , 0.64705884,
        0.654902  ],
       [0.64705884, 0.64705884, 0.65882355, ..., 0.6509804 , 0.6392157 ,
        0.6509804 ],
       ...,
       [0.9647059 , 0.9529412 , 0.9254902 , ..., 0.5176471 , 0.49019608,
        0.29411766],
       [0.9764706 , 0.96862745, 0.9490196 , ..., 0.4862745 , 0.48235294,
        0.34117648],
       [0.98039216, 0.9882353 , 0.9647059 , ..., 0.3529412 , 0.43529412,
        0.38039216]], dtype=float32)
In [6]:
#R(0), G(1), B(2)

v0 = pic[:,:,0]
plt.imshow(v0);
In [7]:
#R(0), G(1), B(2)

#filtering by Green

pic[:,:,1]
Out[7]:
array([[0.6509804 , 0.65882355, 0.654902  , ..., 0.65882355, 0.654902  ,
        0.65882355],
       [0.65882355, 0.65882355, 0.6627451 , ..., 0.65882355, 0.6509804 ,
        0.65882355],
       [0.65882355, 0.6509804 , 0.6627451 , ..., 0.654902  , 0.6431373 ,
        0.6509804 ],
       ...,
       [0.4392157 , 0.43137255, 0.43529412, ..., 0.90588236, 0.8901961 ,
        0.7254902 ],
       [0.44705883, 0.44313726, 0.45882353, ..., 0.8901961 , 0.9137255 ,
        0.8235294 ],
       [0.4627451 , 0.45490196, 0.4745098 , ..., 0.78039217, 0.9019608 ,
        0.90588236]], dtype=float32)
In [8]:
#R(0), G(1), B(2)

v1 = pic[:,:,1]
plt.imshow(v1);
In [9]:
#R(0), G(1), B(2)

#filtering by Blue

pic[:,:,2]
Out[9]:
array([[0.627451  , 0.6392157 , 0.63529414, ..., 0.63529414, 0.6313726 ,
        0.6392157 ],
       [0.63529414, 0.63529414, 0.6431373 , ..., 0.63529414, 0.63529414,
        0.6392157 ],
       [0.6313726 , 0.627451  , 0.6392157 , ..., 0.63529414, 0.627451  ,
        0.63529414],
       ...,
       [0.59607846, 0.5921569 , 0.58431375, ..., 0.9764706 , 0.9607843 ,
        0.8       ],
       [0.60784316, 0.6039216 , 0.6039216 , ..., 0.9647059 , 0.98039216,
        0.8784314 ],
       [0.61960787, 0.6156863 , 0.61960787, ..., 0.8627451 , 0.96862745,
        0.9529412 ]], dtype=float32)
In [10]:
#R(0), G(1), B(2)

v2 = pic[:,:,2]
plt.imshow(v2);
In [11]:
#Loading image using the Pillow Library

pic2 = Image.open(r"C:\Users\Mumsie\images\chi2.jpg")
pic2 = pic2.resize((400,400)) #resized image
pic2
Out[11]:
In [12]:
red = pic2.copy()
red = np.array(red) #transforming image to numpy array
red
Out[12]:
array([[[217, 199, 159],
        [220, 202, 162],
        [219, 202, 160],
        ...,
        [183, 183, 183],
        [181, 179, 180],
        [181, 179, 180]],

       [[212, 194, 153],
        [215, 198, 156],
        [216, 199, 155],
        ...,
        [182, 182, 182],
        [183, 181, 182],
        [183, 181, 182]],

       [[214, 197, 154],
        [217, 200, 157],
        [219, 202, 159],
        ...,
        [182, 182, 182],
        [182, 180, 181],
        [183, 181, 182]],

       ...,

       [[230, 249,  64],
        [226, 245,  54],
        [222, 240,  49],
        ...,
        [ 12,  14,   9],
        [  5,   6,   3],
        [  3,   3,   1]],

       [[225, 246,  49],
        [220, 239,  50],
        [215, 233,  48],
        ...,
        [ 10,  13,   7],
        [  5,   5,   2],
        [  4,   3,   3]],

       [[219, 241,  41],
        [217, 238,  47],
        [214, 232,  48],
        ...,
        [  9,  13,   7],
        [  6,   8,   3],
        [  4,   3,   3]]], dtype=uint8)
In [13]:
#applying red filter to image
red[:,:,(1,2)] = 0
plt.imshow(red);
In [14]:
green = pic2.copy()
green = np.array(green) #transforming image to numpy array
green
Out[14]:
array([[[217, 199, 159],
        [220, 202, 162],
        [219, 202, 160],
        ...,
        [183, 183, 183],
        [181, 179, 180],
        [181, 179, 180]],

       [[212, 194, 153],
        [215, 198, 156],
        [216, 199, 155],
        ...,
        [182, 182, 182],
        [183, 181, 182],
        [183, 181, 182]],

       [[214, 197, 154],
        [217, 200, 157],
        [219, 202, 159],
        ...,
        [182, 182, 182],
        [182, 180, 181],
        [183, 181, 182]],

       ...,

       [[230, 249,  64],
        [226, 245,  54],
        [222, 240,  49],
        ...,
        [ 12,  14,   9],
        [  5,   6,   3],
        [  3,   3,   1]],

       [[225, 246,  49],
        [220, 239,  50],
        [215, 233,  48],
        ...,
        [ 10,  13,   7],
        [  5,   5,   2],
        [  4,   3,   3]],

       [[219, 241,  41],
        [217, 238,  47],
        [214, 232,  48],
        ...,
        [  9,  13,   7],
        [  6,   8,   3],
        [  4,   3,   3]]], dtype=uint8)
In [15]:
#applying green filter to image
green[:,:,(0,2)] = 0
plt.imshow(green);
In [16]:
blue = pic2.copy()
blue = np.array(blue) #transforming image to numpy array
blue
Out[16]:
array([[[217, 199, 159],
        [220, 202, 162],
        [219, 202, 160],
        ...,
        [183, 183, 183],
        [181, 179, 180],
        [181, 179, 180]],

       [[212, 194, 153],
        [215, 198, 156],
        [216, 199, 155],
        ...,
        [182, 182, 182],
        [183, 181, 182],
        [183, 181, 182]],

       [[214, 197, 154],
        [217, 200, 157],
        [219, 202, 159],
        ...,
        [182, 182, 182],
        [182, 180, 181],
        [183, 181, 182]],

       ...,

       [[230, 249,  64],
        [226, 245,  54],
        [222, 240,  49],
        ...,
        [ 12,  14,   9],
        [  5,   6,   3],
        [  3,   3,   1]],

       [[225, 246,  49],
        [220, 239,  50],
        [215, 233,  48],
        ...,
        [ 10,  13,   7],
        [  5,   5,   2],
        [  4,   3,   3]],

       [[219, 241,  41],
        [217, 238,  47],
        [214, 232,  48],
        ...,
        [  9,  13,   7],
        [  6,   8,   3],
        [  4,   3,   3]]], dtype=uint8)
In [17]:
#applying red filter to image
blue[:,:,(0,1)] = 0
plt.imshow(blue);
In [18]:
#applying this on a black and white image (please note that it is uncertain if this image is an original black&white image)
pic8 = Image.open(r"C:\Users\Mumsie\images\ibem.jpg")
pic8 = pic8.resize((400,400)) #resized image
pic8
Out[18]:
In [19]:
green = pic8.copy()
green = np.array(green) #transforming image to numpy array
green
Out[19]:
array([[[255, 255, 255],
        [255, 255, 255],
        [255, 255, 255],
        ...,
        [255, 255, 255],
        [255, 255, 255],
        [255, 255, 255]],

       [[255, 255, 255],
        [255, 255, 255],
        [255, 255, 255],
        ...,
        [255, 255, 255],
        [255, 255, 255],
        [255, 255, 255]],

       [[255, 255, 255],
        [255, 255, 255],
        [255, 255, 255],
        ...,
        [255, 255, 255],
        [255, 255, 255],
        [255, 255, 255]],

       ...,

       [[212, 212, 212],
        [142, 142, 142],
        [ 92,  92,  92],
        ...,
        [255, 255, 255],
        [255, 255, 255],
        [255, 255, 255]],

       [[191, 191, 191],
        [138, 138, 138],
        [ 89,  89,  89],
        ...,
        [255, 255, 255],
        [255, 255, 255],
        [255, 255, 255]],

       [[182, 182, 182],
        [137, 137, 137],
        [101, 101, 101],
        ...,
        [255, 255, 255],
        [255, 255, 255],
        [255, 255, 255]]], dtype=uint8)
In [20]:
#applying green filter to image
green[:,:,(0,2)] = 0
plt.imshow(green);
In [21]:
#turning the image to gray using Numpy
#index 0-2 gives different shades of gray

gray = pic2.copy()
gray = np.array(gray)
gray = gray[:,:,1]
plt.imshow(gray, cmap='gray');
In [22]:
#rotating images. 
#This uses the pillow libraray, and we can rotate using any angle we prefer (90, 240, 180, etc.)

pic2.rotate(90)
Out[22]:
In [23]:
#exploring the cv lib
cv_image = cv2.imread(r"C:\Users\Mumsie\images\chi2.jpg")
cv_image
Out[23]:
array([[[158, 198, 216],
        [161, 201, 219],
        [163, 203, 221],
        ...,
        [180, 179, 181],
        [179, 178, 180],
        [180, 179, 181]],

       [[156, 196, 214],
        [158, 198, 216],
        [160, 200, 218],
        ...,
        [181, 180, 182],
        [182, 181, 183],
        [182, 181, 183]],

       [[152, 192, 210],
        [154, 194, 212],
        [154, 197, 214],
        ...,
        [183, 182, 184],
        [182, 181, 183],
        [182, 181, 183]],

       ...,

       [[ 51, 246, 226],
        [ 49, 244, 224],
        [ 50, 240, 221],
        ...,
        [  1,   3,   3],
        [  3,   3,   3],
        [  3,   3,   3]],

       [[ 44, 243, 222],
        [ 46, 241, 221],
        [ 48, 238, 219],
        ...,
        [  4,   6,   6],
        [  5,   5,   5],
        [  3,   3,   3]],

       [[ 43, 240, 218],
        [ 44, 240, 218],
        [ 48, 239, 218],
        ...,
        [  3,   8,   6],
        [  1,   3,   3],
        [  4,   4,   4]]], dtype=uint8)
In [24]:
plt.imshow(cv_image);

#the cv lib has the color orientation (BGR) different from other libraries (RGB), hence the different image colour.
In [25]:
cv2_image2 = cv2.cvtColor(cv_image, cv2.COLOR_BGR2RGB)
plt.imshow(cv2_image2);
In [26]:
#to rotate an image in cv lib, use the flip function 
#1 flips on its x - axis like a mirror image; -1 flips it on its y axis)

pic_flip = cv2.flip(cv2_image2, 1)
plt.imshow(pic_flip);
In [27]:
pic_flip = cv2.flip(cv2_image2, -1)
plt.imshow(pic_flip);
In [28]:
#creating an image canvas

cav = np.zeros((1000,1000, 3))
plt.imshow(cav);
In [29]:
#drawing shapes inside the canvas (rectangle, circle, etc)

cv2.rectangle(cav,pt1=(200,200),pt2=(800,800),color=(60,150,255),thickness = 8)
plt.imshow(cav);
Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).
In [30]:
#creating a circle

#create another blank canvas

cav2 = np.zeros((1000,1000, 3))
plt.imshow(cav2);
In [31]:
cv2.circle(cav2, center=(500,500), radius=300, color=(0,150,68), thickness=9)
plt.imshow(cav2);
Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).
In [32]:
#to fill out the center of the circle, change the thickness to -1

cv2.circle(cav2, center=(500,500), radius=300, color=(0,150,68), thickness=-1)
plt.imshow(cav2);
Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).
In [33]:
#drawing multiple circles
#create a blank canvas (or create a copy of a previous blank canvas using .copy())

cav3 = np.zeros((1000,1000, 3))
plt.imshow(cav3);
In [34]:
cv2.circle(cav3, center=(500,500), radius=300, color=(0,150,68), thickness=7)
cv2.circle(cav3, center=(350,300), radius=200, color=(68,0,150), thickness=9)
cv2.circle(cav3, center=(200,620), radius=200, color=(130,99,0), thickness=7)
plt.imshow(cav3);
Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).
In [35]:
#drawing multiple circles
#create a blank canvas (or create a copy of a previous blank canvas using .copy())

cav4 = np.zeros((1000,1000))
plt.imshow(cav4);
In [38]:
red = cav4.copy()
blue = cav4.copy()
green = cav4.copy()

red[200:400,200:400] = 225
blue[250:450,250:450] = 225
green[300:500,300:500] = 225

red = Image.fromarray(red).convert("L")
blue = Image.fromarray(blue).convert("L")
green = Image.fromarray(green).convert("L")

pic = Image.merge("RGB",[red,blue,green])
plt.imshow(pic);
In [39]:
# Traffic Light

# Create a blank white canvas
canvas = np.ones((1000, 1000, 3), dtype=np.uint8) * 255

# Draw the traffic light box on the canvas
cv2.rectangle(canvas, (380, 50), (620, 940), (0, 0, 0), thickness=-1)

# Draw the pole
cv2.rectangle(canvas, (480, 900), (520, 1000), (0, 0, 0), thickness=-1)

# Draw the circles for the traffic light on the canvas using BGR colors
cv2.circle(canvas, center=(500, 200), radius=140, color=(0, 0, 255), thickness=-1) #Red light (BGR: Red)
cv2.circle(canvas, center=(500, 500), radius=140, color=(0, 255, 255), thickness=-1)  #Yellow light (BGR: Yellow)
cv2.circle(canvas, center=(500, 800), radius=140, color=(0, 255, 0), thickness=-1)  #Green light (BGR: Green)

#I will convert the BGR color convention for OpenCV to RGB
canvas = cv2.cvtColor(canvas, cv2.COLOR_BGR2RGB)

# Show the traffic light
plt.imshow(canvas)
plt.axis('off')  # Turn off the axis
plt.show()

RESOURCES¶

  • what is a digital image?
  • Real Python image processing
  • Open CV documentation
  • Pillow Documentation
  • Image processing